\chapter{\riscv{}}
\label{chapter-backend-risc-v}

This chapter supplies the details omitted in the description of the
default calling conventions in \refChap{chap-calling-conventions}.

\section{Register usage}
\label{sec-backend-risc-v-register-usage}

The \riscv{} manual contains the following table concerning the register
use in the C ABI:

{\small
\begin{tabular}{|l|l|l|l|}
  \hline
  Register & ABI Name & Description & Saver\\
  \hline
  \hline
  x0 & zero & Hard-wired zero & -\\
  x1 & ra & Return address & Caller\\
  x2 & sp & Stack pointer & Callee\\
  x3 & gp & Global pointer & -\\
  x4 & tp & Thread pointer & -\\
  x5-x7 & t0-t2 & Temporaries & Caller\\
  x8 & s0/fp & Saved register/frame pointer & Callee\\
  x9 & s1 & Saved register & Callee\\
  x10-x11 & a0-a1 & Function arguments/return values & Caller\\
  x12-x17 & a2-a7 & Function arguments & Caller\\
  x18-x27 & s2-s11 & Saved registers & Callee\\
  x28-x31 & t3-t6 & Temporaries & Caller\\
  \hline
  f0-f7 & ft0-ft7 & FP temporaries & Caller\\
  f8-f9 & fs0-fs1 & FP saved registers & Callee\\
  f10-f11 & fa0-fa1 & FP arguments/return values & Caller\\
  f12-f17 & fa2-fa7 & FP arguments & Caller\\
  f18-f27 & fs2-fs11 & FP saved registers & Callee\\
  f28-f31 & ft8-ft11 & FP temporaries & Caller\\
  \hline
\end{tabular}}

As explained in \refChap{chap-calling-conventions}, in \sysname{} we
do not use callee-saves registers, and for the default calling
conventions, we do not use registers to pass arguments.  The
corresponding table for \sysname{} becomes:

{\small
\begin{tabular}{|l|l|l|}
  \hline
  Register & Description & Saver\\
  \hline
  \hline
  x0 & Hard-wired zero & -\\
  x1 & Return address & Caller\\
  x2 & Stack pointer & Caller\\
  x3 & Global pointer & -\\
  x4 & Thread pointer & -\\
  x5 & Static environment & Caller\\
  x6 & Dynamic environment & Caller\\
  x7 & Frame pointer return (see below) & Caller\\
  x8 & Frame pointer & Caller\\
  x9 & Temporary & Caller\\
  x10 & Temporary / first return value & Caller\\
  x11 & Temporary & Caller\\
  x12-x31 & Temporaries & Caller\\
  \hline
  f0-f31 & FP temporaries & Caller\\
  \hline
\end{tabular}}

\section{Calling conventions}
\label{sec-backend-risc-v-calling-conventions}

\subsection{Normal call}

In the standard \riscv{} calling convention, the stack pointer is
aligned to $16$ bytes, but we are not using the standard \riscv{}
calling convention anyway, so there is no reason to respect this
restriction.

Actions by the caller to call the callee:

\begin{enumerate}
\item Compute the callee function and the arguments into temporary
  locations.
\item Load the rack of the callee into a temporary register.
\item Load the static environment from the rack of the callee into the
  register dedicated for the static environment (x5).
\item Load the frame size for the callee from the rack of the
  callee, and put the result in some register, say $rf$.
\item Load the entry point for the callee from the rack of the callee,
  and put the result in some register, say $re$.
\item The number of arguments is known statically, say $A$.  Let $N$
  be $A$ plus $3$ ($1$ for the saved caller frame pointer, one for the
  slot to hold the return address, and $1$ for the call-site
  descriptor).
\item Save the stack pointer (x2) in some available register, say $rs$.
\item Subtract the contents of $rf + N \cdot 8$ from the stack
  pointer (x2).
\item Store the caller frame pointer (x8) on the stack at location $rs
  - 8$.
\item Store the call-site descriptor on the stack at location $rs -
  24$.
\item Store arguments into locations $sp +  0$, $sp +  1$, etc. but in
  reverse order, so that the last argument is on top of the stack.
\item Load the dynamic environment into its dedicated register (x6).
\item Save registers that are needed after the callee returns on the
  stack, in particular $rs$.
\item Copy the $rs$ register into the frame pointer (x8), thereby
  establishing the stack frame for the callee.
\item Call the entry point in $re$ using the JALR instruction with
  $re$ as the source register and x1 as the target register.
\end{enumerate}

Prelude:

\begin{enumerate}
\item Store the return address in x1 in the stack frame in the
  location dedicated for this purpose ($fp - 16$).
\item Parse the arguments and store the result in registers, or in the
  stack frame. The number of arguments (say $A$) can be
  computed as $fp$ - 24 - $F$ - $sp$ divided by $16$, where $F$ is the
  frame size, which is known statically.
\item Remove the arguments from the stack by adding $A \cdot 8$ to the
  stack.  This is the state of the callee that is used by the
  call-site manager to supply arguments directly, thereby avoiding
  argument parsing. 
\end{enumerate}

Actions by the callee to return to caller:

\begin{enumerate}
\item Compute return values into temporary locations.
\item Load the return address from the stack (in $fp - 16$) into x1.
\item
  \begin{enumerate}
  \item If no values are to be returned, store \texttt{nil} in x10.
    Then load $fp - 8$ into x7 so that x7 now contains the saved frame
    pointer of the caller.  Finally copy $fp$ into $sp$ indicating
    that there are no return values.
  \item Otherwise, store the return values other than the first one on
    the stack in locations $fp - 16$, $fp - 24$, etc.  Then load $fp -
    8$ into x7 so that x7 now contains the saved frame pointer of the
    caller.  Then put the first return value in x10.  Finally store
    $fp - V \cdot 8$ in $sp$, where $V$ is the number of values to be
    returned.
  \end{enumerate}
\item Return to the caller.
\end{enumerate}

Actions by the caller after the callee returns.  For the case when
this call is an argument to \texttt{multiple-value-call}, refer to
\refSec{sec-implementing-multiple-value-call} for actions after the
callee returns.  Here, we describe only the case where the call is not
one of the arguments to \texttt{multiple-value-call}.  Then, a single
return value is required.

\begin{enumerate}
\item Copy x7 into $fp$ thereby re-establishing the stack frame of the
  caller.
\item Load the saved $rs$ from the stack into $rs$.
\item Use the value in x10.
\item Copy $rs$ to $sp$ thereby removing the return values from the
  stack and restoring $sp$ to its value before the call.
\end{enumerate}

% LocalWords:  callee
